package petertel.pbx.utils;

import java.util.List;
import java.util.Stack;

import petertel.pbx.connector.Executor;
import petertel.pbx.utils.ConfigItem.Flag;

public class GenericConfigWriter {
	public static void write(Executor executor,
			List<? extends ConfigItem> itemList, String filename) {
		StringBuilder command = new StringBuilder();
		command.append("sed -i ");
		Stack<Range> stack = new Stack<Range>();
		for (int i = 0; i < itemList.size(); i++) {
			ConfigItem item = itemList.get(i);
			Flag flag = item.getFlag();
			if (stack.isEmpty()
					|| itemList.get(stack.peek().end).getFlag() != flag) {
				stack.push(new Range(i, i));
			} else {
				stack.peek().end = i;
			}
		}

		int position = 0;
		while (!stack.isEmpty()) {
			Range range = stack.pop();
			Flag flag = itemList.get(range.end).getFlag();
			if (flag == Flag.insert) {
				if (position == 0)
					for (int i = range.start; i <= range.end; i++) {
						ConfigItem item = itemList.get(i);
						String line = item.getLine();
						command.append("-e '$a" + line).append("' \\\n");
					}
				else
					for (int i = range.end; i >= range.start; i--) {
						ConfigItem item = itemList.get(i);
						String line = item.getLine();
						command.append("-e '" + position + "i" + line).append(
								"' \\\n");
					}
			} else if (flag == Flag.delete) {
				for (int i = range.end; i >= range.start; i--) {
					ConfigItem item = itemList.get(i);
					command.append("-e '" + item.getLineno() + "d").append(
							"' \\\n");
				}
			} else if (flag == Flag.update) {
				for (int i = range.start; i <= range.end; i++) {
					ConfigItem item = itemList.get(i);
					String line = item.getLine();
					command.append("-e '" + item.getLineno() + "c" + line)
							.append("' \\\n");
				}
				position = itemList.get(range.start).getLineno();
			} else {
				position = itemList.get(range.start).getLineno();
			}
		}
		command.append(" " + filename);
		System.out.println(command);
		if (executor != null)
			executor.exec(command.toString());
	}

	private static class Range {
		Range(int start, int end) {
			this.start = start;
			this.end = end;
		}

		int start, end;

		@Override
		public String toString() {
			return start + "," + end;
		}
	}

}
